package org.snp

import java.awt.Point
import java.io.File
import java.io.FileOutputStream

import com.lowagie.text.Document
import com.lowagie.text.pdf.BaseFont
import com.lowagie.text.pdf.PdfCopy
import com.lowagie.text.pdf.PdfStamper
import com.lowagie.text.pdf.PdfReader

import org.slf4j.LoggerFactory

/**
 * Construct with list of voters, address box position information and
 * an output file name.
 * Then call generate to poop out target PDF
 */
class PDFMerger(points: List[Point], voters: List[Option[Voter]], inFile: File, outFile: File) {

  //the number of output pages to generate
  private val noPages: Int = if ((voters.size - 1) % points.size == 0)
    (voters.size - 1) / points.size
  else
    (voters.size - 1) / points.size + 1
  private val tmpOutFile = new File(outFile.getAbsolutePath + ".tmp")

  private val log = LoggerFactory.getLogger(this.getClass);

  def generate() {
    generateCopy()
    val helv = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED)
    val reader = new PdfReader(tmpOutFile.getAbsolutePath);
    val stamp = new PdfStamper(reader, new FileOutputStream(outFile));

    //TODO use insertPage, not a seperate copy step?
    //for( i <- 1 until noPages ) {
    //	stamp.insertPage(1,PageSize.A4)
    //	stamp.replacePage(reader,1,1)
    //}

    // change the content
    var voters = this.voters
    for (i <- 1 to noPages) {
      var over = stamp.getOverContent(i)

      log.debug("got page " + i)
      for (point <- points.sort(_.y > _.y)) { //sort rectangles down the screen
        if (voters.length != 0) {
          if (voters.head.isDefined) {
            val voter = voters.head.get //need to stop modifying lists I am looping over!
            voters = voters.tail
            log.debug("writing to:" + point.x + "," + point.y)
            over.setFontAndSize(helv, 11) //need to autoscale this
            over.beginText()
            //over.moveText(rectangle.x,rectangle.y + rectangle.height)
            over.setTextMatrix(point.x, point.y)
            over.setLeading(11)
            over.newlineText() //massive fudge
            //over.newlineText()
            //over.showTextAlignedKerned(Element.ALIGN_LEFT,"POOP\npoop", rectangle.x, rectangle.y, 0);
            over.showText(voter.registerNum)
            over.newlineShowText(voter.firstName + " " + voter.lastName)
            if (voter.aline1 != null && voter.aline1 != "")
              over.newlineShowText(voter.aline1)
            over.newlineShowText(voter.aline2)
            over.newlineShowText(voter.city + " " + voter.postcode)
            over.endText()
          } else voters = voters.tail
        }
      }
    }

    stamp.close()
    log.info("PDF Generated.")
  }

  private def generateCopy() {
    val reader = new PdfReader(inFile.getAbsolutePath);
    val document = new Document(reader.getPageSizeWithRotation(1));
    val copy = new PdfCopy(document, new FileOutputStream(tmpOutFile)); //Will work with PDFStamper too
    document.open();
    val page = copy.getImportedPage(reader, 1);
    for (i <- 1 to noPages)
      copy.addPage(page);
    document.close();
  }

}
